package com.weixin.message;

import java.awt.Color;
import java.awt.Font;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.media.MediaUploadResult;
import com.foxinmy.weixin4j.model.qr.QRParameter;
import com.foxinmy.weixin4j.model.qr.QRResult;
import com.foxinmy.weixin4j.mp.WeixinProxy;
import com.foxinmy.weixin4j.mp.api.MediaApi;
import com.foxinmy.weixin4j.mp.api.NotifyApi;
import com.foxinmy.weixin4j.mp.api.QrApi;
import com.foxinmy.weixin4j.mp.message.NotifyMessage;
import com.foxinmy.weixin4j.tuple.Text;
import com.weixin.message.common.WeixinMessageProcessor;
import com.weixin.message.common.message.Image;
import com.weixin.message.common.message.WeixinResponse;
import com.weixin.message.common.message.req.ImageMessage;
import com.weixin.message.common.message.req.LinkMessage;
import com.weixin.message.common.message.req.LocationMessage;
import com.weixin.message.common.message.req.TextMessage;
import com.weixin.message.common.message.req.VoiceMessage;
import com.weixin.message.common.message.req.event.EventMessage;
import com.weixin.message.common.message.resp.ImageResponse;
import com.weixin.message.common.message.resp.NoReplyResponse;
import com.weixin.message.common.message.resp.TextResponse;
import com.weixin.message.common.util.ImageHandleHelper;
import com.weixin.message.common.util.ShaSign;

/**
 * 消息处理
 *
 */
public class MessageProcessor extends WeixinMessageProcessor {

	private static Logger logger = LoggerFactory.getLogger(MessageProcessor.class);

	private static final String ACCESS_TOKEN = "3243erttrt565rr3ertfgr5yfy66hgg";
	private static final String ACCESS_SECRET = "132fffrtthh55433grgddw24234";
	private static final String SERVER = "http://localhost:9157/manage";

	@Override
	protected WeixinResponse onText(TextMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse("您发的消息为:" +
		// message.getContent(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onImage(ImageMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse("您发的图片为:" +
		// message.getPicUrl(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onLink(LinkMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse("您发的链接为:" +
		// message.getUrl(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onLocation(LocationMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse(
		// "您发的地址为: {x=" + message.getLocation_X() + ",y=" +
		// message.getLocation_Y() + "}", message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onVoice(VoiceMessage message) {
		// TextResponse resp =
		// RespMessageFactory.buildTextResponse("您发的语音为:mediaId=" +
		// message.getMediaId(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onEvent(EventMessage message) {
		try {
			RestTemplate restTemplate = new RestTemplate();
			if ("subscribe".equals(message.getEvent())) {// 用户未关注时，进行关注后的事件推送
				String openId = message.getFromUserName();
				String chiefOpenId = "";
				String eventKey = message.getEventKey();
				if ("".equals(eventKey) || null == eventKey) {
					chiefOpenId = "otFms0ib9eecFHRe2pa98b-Bfjh0";
				} else {
					String[] params = eventKey.split("_");
					chiefOpenId = params[1];
				}

				Calendar calendar = Calendar.getInstance();
				ShaSign shaSign = ShaSign.getSign(ACCESS_TOKEN, ACCESS_SECRET, calendar.getTime());
				StringBuilder url = new StringBuilder(SERVER + "/openApi/memberApi/addMemberFromMessage.do");
				url.append("?apiKey=").append(ACCESS_TOKEN);
				url.append("&timestamp=").append(calendar.getTimeInMillis());
				url.append("&openId=").append(openId);
				url.append("&chiefOpenId=").append(chiefOpenId);

				shaSign.addParam("openId", openId);
				shaSign.addParam("chiefOpenId", chiefOpenId);
				url.append("&sign=").append(shaSign.signParams());

				ResponseEntity<String> responseEntity = restTemplate.exchange(url.toString(), HttpMethod.POST, null,
						String.class);
				String resultStr = responseEntity.getBody();
				logger.info("调用addMemberFromMessage.do接口返回结果为：" + resultStr);
				JSONObject jsonObject = JSONObject.parseObject(resultStr);
				String code = jsonObject.getString("code");
				String msg = jsonObject.getString("msg");
				if ("ok".equals(code)) {
					JSONObject memberObject = jsonObject.getJSONObject("object");
					String cardNo = memberObject.getString("cardNo");
					TextResponse textResponse = new TextResponse();
					textResponse.setToUserName(openId);
					textResponse.setFromUserName(message.getToUserName());
					// if ("r".equals(type)) {
					// textResponse.setContent("欢迎来到易贝通，您的ID为：" + cardNo
					// +
					// "，已将100积分存入你的积分账户，请在底部的【个人中心-->我的账户】查看。快快联系客服微信号：1046566144，索取1元现金红包哦！");
					// } else {
					textResponse.setContent("欢迎来到贝通商城，您的ID为：" + cardNo + "，已赠送您100积分，请在底部的【个人中心-->我的账户】查看");
					// }

					textResponse.setFuncFlag(0x0001);
					// try {
					// if ("r".equals(type)) {
					//
					// }
					// } catch (Exception e) {
					// e.printStackTrace();
					// }
					return textResponse;
				} else {
					logger.error("调用addMemberFromMessage.do接口返回错误信息：" + msg);
				}
			} else if ("SCAN".equals(message.getEvent())) {// 用户已关注时的事件

			} else if ("CLICK".equals(message.getEvent())) {// 点击菜单事件
				WeixinProxy weixinProxy = new WeixinProxy();
				String openId = message.getFromUserName();
				if ("123321".equals(message.getEventKey())) {// 点击领二维码菜单
					try {
						NotifyApi notifyApi = new NotifyApi(weixinProxy.getTokenManager());
						notifyApi.sendNotify(new NotifyMessage(openId, new Text("正在为您生成图片，请稍等...")));
					} catch (WeixinException e1) {
						e1.printStackTrace();
					}
					Calendar calendar = Calendar.getInstance();
					ShaSign shaSign = ShaSign.getSign(ACCESS_TOKEN, ACCESS_SECRET, calendar.getTime());
					StringBuilder url = new StringBuilder(SERVER + "/openApi/memberApi/getMember.do");
					url.append("?apiKey=").append(ACCESS_TOKEN);
					url.append("&timestamp=").append(calendar.getTimeInMillis());
					url.append("&openId=").append(openId);
					shaSign.addParam("openId", openId);
					url.append("&sign=").append(shaSign.signParams());

					ResponseEntity<String> responseEntity = restTemplate.exchange(url.toString(), HttpMethod.GET, null,
							String.class);
					String resultStr = responseEntity.getBody();
					logger.info("调用getMember.do接口返回结果为：" + resultStr);
					JSONObject jsonObject = JSONObject.parseObject(resultStr);
					String code = jsonObject.getString("code");
					String msg = jsonObject.getString("msg");
					if ("ok".equals(code)) {
						JSONObject memberObject = jsonObject.getJSONObject("object");
						String avatar = memberObject.getString("avatar");
						String name = memberObject.getString("name");
						// int vipLevel = memberObject.getIntValue("vipLevel");
						// if (vipLevel == 0) {
						// TextResponse textResponse = new TextResponse();
						// textResponse.setToUserName(openId);
						// textResponse.setFromUserName(message.getToUserName());
						// textResponse.setContent("您目前的等级为粉丝，无法进行推广，升级为会员、代理或合伙人后才可推广。");
						// textResponse.setFuncFlag(0x0001);
						// return textResponse;
						// }
						try {
							// 生成带参数的二维码

							QrApi qrApi = new QrApi(weixinProxy.getTokenManager());
							// 创建临时二维码(场景值为string),二维码有效时间，以秒为单位。
							// 最大不超过2592000（即30天）
							QRParameter qRParameter = QRParameter.createTemporaryQR(2592000, openId);
							// QRParameter qRParameter =
							// QRParameter.createTemporaryQR(2592000,
							// "1qw1213wq" +
							// "_n");
							QRResult qRResult = qrApi.createQR(qRParameter);
							byte[] qr = qRResult.getContent();

							// 合并二维码图片
							// File smallImage = new File("d:/" + openId +
							// ".jpg");
							File smallImage = new File("/mnt/images/" + openId + ".jpg");
							OutputStream output = new FileOutputStream(smallImage);
							@SuppressWarnings("resource")
							BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
							bufferedOutput.write(qr);
							// File bigImage = new File("d:/tuiguang.jpg");
							File bigImage = new File("/mnt/images/tuiguang.jpg");
							// File resultFile0 =
							// ImageHandleHelper.overlapImage(bigImage,
							// smallImage,
							// "d:/" + openId + ".jpg",
							// 200, 120, 230, 230);
							File resultFile0 = ImageHandleHelper.overlapImage(bigImage, smallImage,
									"/mnt/images/" + openId + ".jpg", 200, 120, 230, 230);

							// 合并头像
							// new一个URL对象
							URL avatarUrl = new URL(avatar);
							// 打开链接
							HttpURLConnection conn = (HttpURLConnection) avatarUrl.openConnection();
							// 设置请求方式为"GET"
							conn.setRequestMethod("GET");
							// 超时响应时间为5秒
							conn.setConnectTimeout(5 * 1000);
							// 通过输入流获取图片数据
							InputStream inStream = conn.getInputStream();
							// 得到图片的二进制数据，以二进制封装得到数据，具有通用性
							byte[] avatarData = readInputStream(inStream);
							// new一个文件对象用来保存图片，默认保存当前工程根目录
							// File avatarFile = new File("d:/avatar_" + openId
							// +
							// ".jpg");
							File avatarFile = new File("/mnt/images/avatar_" + openId + ".jpg");
							// 创建输出流
							FileOutputStream outStream = new FileOutputStream(avatarFile);
							// 写入数据
							outStream.write(avatarData);
							// 关闭输出流
							outStream.close();

							// File resultFile1 =
							// ImageHandleHelper.overlapImage(resultFile0,
							// avatarFile,
							// "d:/" + openId + ".jpg", 210, 370, 60, 60);
							File resultFile1 = ImageHandleHelper.overlapImage(resultFile0, avatarFile,
									"/mnt/images/" + openId + ".jpg", 210, 370, 60, 60);
							//
							// // 写入昵称
							// File resultFile2 =
							// ImageHandleHelper.exportImg2(name,
							// resultFile1.getPath(),
							// "d:/nameresult_" + openId + ".jpg", 320, 400, 24,
							// Font.PLAIN, Color.red);
							File resultFile2 = ImageHandleHelper.exportImg2(name, resultFile1.getPath(),
									"/mnt/images/nameresult_" + openId + ".jpg", 320, 400, 24, Font.PLAIN, Color.red);
							// 写入日期
							Date expireDate = getBeforeOrNextDay(new Date(), 30);
							// File resultFile3 =
							// ImageHandleHelper.exportImg2(getDateStr(expireDate,
							// "yyyy年MM月dd日"),
							// resultFile2.getPath(), "d:/dateresult_" + openId
							// +
							// ".jpg", 317, 872, 20, Font.PLAIN,
							// Color.black);
							File resultFile3 = ImageHandleHelper.exportImg2(getDateStr(expireDate, "yyyy年MM月dd日"),
									resultFile2.getPath(), "/mnt/images/dateresult_" + openId + ".jpg", 317, 872, 20,
									Font.PLAIN, Color.black);

							// 通过素材管理接口上传合并后的图片到微信服务器
							MediaApi mediaApi = new MediaApi(weixinProxy.getTokenManager());
							MediaUploadResult mediaUploadResult = mediaApi.uploadMedia(false,
									new FileInputStream(resultFile3), openId);
							String mediaId = mediaUploadResult.getMediaId();

							// 返回WeixinResponse
							ImageResponse imageResponse = new ImageResponse();
							imageResponse.setToUserName(openId);
							imageResponse.setFromUserName(message.getToUserName());
							Image image = new Image();
							image.setMediaId(mediaId);
							imageResponse.setImage(image);
							imageResponse.setFuncFlag(0x0001);
							return imageResponse;
						} catch (WeixinException e) {
							e.printStackTrace();
							logger.error("创建二维码图片出现异常", e);
						} catch (FileNotFoundException e) {
							e.printStackTrace();
							logger.error("创建二维码图片出现异常", e);
						} catch (IOException e) {
							e.printStackTrace();
							logger.error("创建二维码图片出现异常", e);
						} catch (Exception e) {
							e.printStackTrace();
							logger.error("创建二维码图片出现异常", e);
						}

					} else {
						logger.error("调用getMember.do接口返回错误信息：" + msg);
					}
				} else if ("888888".equals(message.getEventKey())) {
					TextResponse textResponse = new TextResponse();
					textResponse.setToUserName(openId);
					textResponse.setFromUserName(message.getToUserName());
					textResponse.setContent("用户通过你的二维码关注公众号后，你将获得10积分和1贝币（1贝币=1元），且该用户永久成为你的下级。积分可换购商品或转化为贝币，贝币可直接提现。");
					textResponse.setFuncFlag(0x0001);
					return textResponse;
				}

			} else if ("unsubscribe".equals(message.getEvent())) {
				String openId = message.getFromUserName();
				Calendar calendar = Calendar.getInstance();
				ShaSign shaSign = ShaSign.getSign(ACCESS_TOKEN, ACCESS_SECRET, calendar.getTime());
				StringBuilder url = new StringBuilder(SERVER + "/openApi/memberApi/setMemberUnfllow.do");
				url.append("?apiKey=").append(ACCESS_TOKEN);
				url.append("&timestamp=").append(calendar.getTimeInMillis());
				url.append("&openId=").append(openId);
				shaSign.addParam("openId", openId);
				url.append("&sign=").append(shaSign.signParams());
				ResponseEntity<String> responseEntity = restTemplate.exchange(url.toString(), HttpMethod.POST, null,
						String.class);
				String resultStr = responseEntity.getBody();
				logger.info("调用setMemberUnfllow.do接口返回结果为：" + resultStr);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return NoReplyResponse.get();// ruturn后可以回复用户消息
	}

	private byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		// 创建一个Buffer字符串
		byte[] buffer = new byte[1024];
		// 每次读取的字符串长度，如果为-1，代表全部读取完毕
		int len = 0;
		// 使用一个输入流从buffer里把数据读取出来
		while ((len = inStream.read(buffer)) != -1) {
			// 用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
			outStream.write(buffer, 0, len);
		}
		// 关闭输入流
		inStream.close();
		// 把outStream里的数据写入内存
		return outStream.toByteArray();
	}

	private Date getBeforeOrNextDay(Date date, int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, n);
		date = calendar.getTime();
		return date;
	}

	private String getDateStr(Date date, String pattern) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(date);
	}
}
